package com.lhz.framework.security.manager.impl;

import com.lhz.common.constant.TokenConstant;
import com.lhz.project.system.model.entity.auth.User;
import com.lhz.framework.security.manager.TokenManager;
import com.lhz.framework.security.HolderUserInfo;
import com.lhz.common.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import cn.hutool.core.util.StrUtil;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 基于redis的token管理器
 *
 * @author LiGezZ
 */
@Component
@Slf4j
public class RedisTokenManager implements TokenManager {

    /**
     * 缓存用户token
     *
     * @param tokenInfo
     * @param tokenKey
     * @param username
     * @return
     */
    @Override
    public void saveUserToken(String tokenKey, String username, String userId, HolderUserInfo tokenInfo) {
        //判断账户是否已经登陆
        String userIdKey = TokenConstant.TOKEN_REDIS_KEY + userId;
        // token key：以登录应用区分，同一应用限制多登录，不同应用可以同时登录
        if (RedisUtils.hasKey(userIdKey)) {
            String oldToken = RedisUtils.get(userIdKey).toString();
            RedisUtils.del(userIdKey, oldToken);
        }
        // 绑定用户Id与token关系
        RedisUtils.set(userIdKey, tokenKey);
        //用户名
        RedisUtils.hset(tokenKey, TokenConstant.USER_ACCOUNT_KEY, username);
        //一用户id
        RedisUtils.hset(tokenKey, TokenConstant.USER_ID_KEY, userId);
        //用户信息
        RedisUtils.hset(tokenKey, TokenConstant.USER_INFO_KEY, tokenInfo);

        //设置缓存时间
        RedisUtils.expire(userIdKey, TokenConstant.TOKEN_EXPIRY, TimeUnit.SECONDS);
        RedisUtils.expire(tokenKey, TokenConstant.TOKEN_EXPIRY, TimeUnit.SECONDS);
    }

    /**
     * 删除key
     *
     * @param tokenKey key
     */
    @Override
    public void removeUserToken(String tokenKey) {
        // 获取缓存用户Id
        User user = (User) RedisUtils.hget(tokenKey, TokenConstant.USER_INFO_KEY);
        if (user != null) {
            // 删除缓存账号及用户 token 信息
            String userIdKey = TokenConstant.TOKEN_REDIS_KEY + user.getId();
            RedisUtils.del(userIdKey, tokenKey);
        }
    }

    /**
     * 检查key是否存在
     *
     * @param key
     * @return
     */
    @Override
    public boolean hasKey(String key) {
        return RedisUtils.hasKey(key);
    }

    /**
     * 刷新用户登录过期时间
     *
     * @param tokenKey 用户token信息
     */
    @Override
    public void refreshExpire(String tokenKey) {
        //获取用户userIdKey
        String userId = getUser(tokenKey, TokenConstant.USER_ID_KEY).toString();
        String userIdKey = TokenConstant.TOKEN_REDIS_KEY + userId;
        if (StrUtil.isNotEmpty(tokenKey) && StrUtil.isNotEmpty(userIdKey)) {
            RedisUtils.expire(userIdKey, TokenConstant.TOKEN_EXPIRY, TimeUnit.SECONDS);
            RedisUtils.expire(tokenKey, TokenConstant.TOKEN_EXPIRY, TimeUnit.SECONDS);
        }
    }

    /**
     * 获取用户的所有登录信息
     *
     * @param tokenKey
     * @param dataKey
     * @return
     */
    @Override
    public Object getUser(String tokenKey, String dataKey) {
        return RedisUtils.hget(tokenKey, dataKey);
    }

    /**
     * 通过token获取用户的所有登录信息
     *
     * @param tokenKey
     * @return
     */
    @Override
    public Map<Object, Object> getUserInfoByToken(String tokenKey) {
        return RedisUtils.hGetAll(tokenKey);
    }

}
